/**
 * 
 * @Project le cOeur - Data Virtualization
 * @Date 08.12.2012
 * @Author Aebi Pascal, Kocher Marc
 * @School BFH-TI Biel, Bachelor Thesis
 *
 */

package main.framework.security;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;

import main.framework.setting.Config;

/**
 * The class KeyStoreManager is responsible for the management of the different certificates.
 */
public class KeyStoreManager {
	
	private KeyStore keyStore;
	private KeyManagerFactory keyManagerFactory;
	private KeyStore trustStore;
	private TrustManagerFactory trustManagerFactory;
	
	/**
	 * Creates a key store manager.
	 * 
	 * @throws KeyStoreException If no Provider supports a KeyStoreSpi implementation for the specified type.
	 * @throws NoSuchAlgorithmException If no Provider supports a KeyManagerFactorySpi implementation for the specified algorithm.
	 */
	public KeyStoreManager() throws KeyStoreException, NoSuchAlgorithmException {
		this.keyStore = KeyStore.getInstance(Config.KEY_STORE_TYPE);
		this.trustStore = KeyStore.getInstance(Config.TRUST_STORE_TYPE);
		this.keyManagerFactory = KeyManagerFactory.getInstance(Config.KEY_STORE_ALGORITHM);
		this.trustManagerFactory = TrustManagerFactory.getInstance(Config.TRUST_STORE_ALGORITHM);
	}
	
	/**
	 * Loads and initializes the key and the trust store.
	 * 
	 * @throws NoSuchAlgorithmException If the algorithm used to check the integrity of the keystore cannot be found.
	 * @throws CertificateException If any of the certificates in the keystore could not be loaded.
	 * @throws FileNotFoundException If the file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading.
	 * @throws IOException If there is an I/O or format problem with the keystore data, if a password is required but not given, or if the given password was incorrect. If the error is due to a wrong password, the cause of the IOException should be an UnrecoverableKeyException.
	 * @throws UnrecoverableKeyException If the key cannot be recovered (e.g. the given password is wrong).
	 * @throws KeyStoreException If the init operation fails.
	 */
	public void initKeyStores() throws NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyStoreException {
		this.keyStore.load(new FileInputStream(Config.KEY_STORE_PATH), Config.KEY_STORE_PW.toCharArray());
		this.keyManagerFactory.init(this.keyStore, Config.KEY_STORE_PW.toCharArray());
        this.trustStore.load(new FileInputStream(Config.TRUST_STORE_PATH), Config.TRUST_STORE_PW.toCharArray());
        this.trustManagerFactory.init(this.trustStore);
	}
	
	/**
	 * Returns one key manager for each type of key material.
	 * 
	 * @return The key managers.
	 */
	public KeyManager[] getKeyManagers() {
		return this.keyManagerFactory.getKeyManagers();
	}
	
	/**
	 * Returns one trust manager for each type of trust material.
	 * 
	 * @return The trust managers.
	 */
	public TrustManager[] getTrustManagers() {
		return this.trustManagerFactory.getTrustManagers();
	}
	
	/**
	 * Returns the key store.
	 * 
	 * @return The key store.
	 */
	public KeyStore getKeyStore() {
		return this.keyStore;
	}

	/**
	 * Returns the trust store.
	 * 
	 * @return The trust store.
	 */
	public KeyStore getTrustStore() {
		return this.trustStore;
	}
	
}
